From 2a2726fd6294e16be2093438a7d9a15fb25f46b5 Mon Sep 17 00:00:00 2001 From: "djm@kirby.fc.hp.com" Date: Wed, 30 Jun 2004 23:08:19 +0000 Subject: [PATCH] bitkeeper revision 1.1041.2.4 (40e347e3mOn-qpOvThklRxuxrNeFVQ) More changes to encapsulate shadow mode Changes to move machdep dom0 ops to machdep file --- .rootkeys | 1 + xen/arch/x86/dom0_ops.c | 223 ++++++++++++++++++++++++++++++++++++++++ xen/common/debug.c | 2 +- xen/common/dom0_ops.c | 182 +------------------------------- xen/common/domain.c | 5 +- xen/common/kernel.c | 1 - 6 files changed, 229 insertions(+), 185 deletions(-) create mode 100644 xen/arch/x86/dom0_ops.c diff --git a/.rootkeys b/.rootkeys index 26357f0617..d0ce50f487 100644 --- a/.rootkeys +++ b/.rootkeys @@ -305,6 +305,7 @@ 3ddb79bcsjinG9k1KcvbVBuas1R2dA xen/arch/x86/apic.c 3ddb79bcSC_LvnmFlX-T5iTgaR0SKg xen/arch/x86/boot/boot.S 3ddb79bcUrk2EIaM5VsT6wUudH1kkg xen/arch/x86/delay.c +40e34414WiQO4h2m3tcpaCPn7SyYyg xen/arch/x86/dom0_ops.c 3e32af9aRnYGl4GMOaDKp7JdfhOGhg xen/arch/x86/domain_page.c 3ddb79bcecupHj56ZbTa3B0FxDowMg xen/arch/x86/entry.S 3ddb79bcY5zW7KhvI9gvfuPi3ZumEg xen/arch/x86/extable.c diff --git a/xen/arch/x86/dom0_ops.c b/xen/arch/x86/dom0_ops.c new file mode 100644 index 0000000000..1ec26d583d --- /dev/null +++ b/xen/arch/x86/dom0_ops.c @@ -0,0 +1,223 @@ +/****************************************************************************** + * Arch-specific dom0_ops.c + * + * Process command requests from domain-0 guest OS. + * + * Copyright (c) 2002, K A Fraser + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TRC_DOM0OP_ENTER_BASE 0x00020000 +#define TRC_DOM0OP_LEAVE_BASE 0x00030000 + +extern unsigned int alloc_new_dom_mem(struct domain *, unsigned int); + +static int msr_cpu_mask; +static unsigned long msr_addr; +static unsigned long msr_lo; +static unsigned long msr_hi; + +static void write_msr_for(void *unused) +{ + if (((1 << current->processor) & msr_cpu_mask)) + wrmsr(msr_addr, msr_lo, msr_hi); +} + +static void read_msr_for(void *unused) +{ + if (((1 << current->processor) & msr_cpu_mask)) + rdmsr(msr_addr, msr_lo, msr_hi); +} + +long arch_do_dom0_op(dom0_op_t *op, dom0_op_t *u_dom0_op) +{ + long ret = 0; + + if ( !IS_PRIV(current) ) + return -EPERM; + + switch ( op->cmd ) + { + + case DOM0_MSR: + { + if ( op->u.msr.write ) + { + msr_cpu_mask = op->u.msr.cpu_mask; + msr_addr = op->u.msr.msr; + msr_lo = op->u.msr.in1; + msr_hi = op->u.msr.in2; + smp_call_function(write_msr_for, NULL, 1, 1); + write_msr_for(NULL); + } + else + { + msr_cpu_mask = op->u.msr.cpu_mask; + msr_addr = op->u.msr.msr; + smp_call_function(read_msr_for, NULL, 1, 1); + read_msr_for(NULL); + + op->u.msr.out1 = msr_lo; + op->u.msr.out2 = msr_hi; + copy_to_user(u_dom0_op, op, sizeof(*op)); + } + ret = 0; + } + break; + + case DOM0_GETDOMAININFO: + { + full_execution_context_t *c; + struct domain *d; + unsigned long flags; + int i; + + read_lock_irqsave(&tasklist_lock, flags); + + for_each_domain ( d ) + { + if ( d->domain >= op->u.getdomaininfo.domain ) + break; + } + + if ( (d == NULL) || !get_domain(d) ) + { + read_unlock_irqrestore(&tasklist_lock, flags); + ret = -ESRCH; + break; + } + + read_unlock_irqrestore(&tasklist_lock, flags); + + op->u.getdomaininfo.domain = d->domain; + strcpy(op->u.getdomaininfo.name, d->name); + + op->u.getdomaininfo.flags = + (test_bit(DF_DYING, &d->flags) ? DOMFLAGS_DYING : 0) | + (test_bit(DF_CRASHED, &d->flags) ? DOMFLAGS_CRASHED : 0) | + (test_bit(DF_SHUTDOWN, &d->flags) ? DOMFLAGS_SHUTDOWN : 0) | + (test_bit(DF_CTRLPAUSE, &d->flags) ? DOMFLAGS_PAUSED : 0) | + (test_bit(DF_BLOCKED, &d->flags) ? DOMFLAGS_BLOCKED : 0) | + (test_bit(DF_RUNNING, &d->flags) ? DOMFLAGS_RUNNING : 0); + + op->u.getdomaininfo.flags |= d->processor << DOMFLAGS_CPUSHIFT; + op->u.getdomaininfo.flags |= + d->shutdown_code << DOMFLAGS_SHUTDOWNSHIFT; + + op->u.getdomaininfo.tot_pages = d->tot_pages; + op->u.getdomaininfo.max_pages = d->max_pages; + op->u.getdomaininfo.cpu_time = d->cpu_time; + op->u.getdomaininfo.shared_info_frame = + __pa(d->shared_info) >> PAGE_SHIFT; + + if ( op->u.getdomaininfo.ctxt != NULL ) + { + if ( (c = kmalloc(sizeof(*c))) == NULL ) + { + ret = -ENOMEM; + put_domain(d); + break; + } + + if ( d != current ) + domain_pause(d); + + c->flags = 0; + memcpy(&c->cpu_ctxt, + &d->shared_info->execution_context, + sizeof(d->shared_info->execution_context)); + if ( test_bit(DF_DONEFPUINIT, &d->flags) ) + c->flags |= ECF_I387_VALID; + memcpy(&c->fpu_ctxt, + &d->thread.i387, + sizeof(d->thread.i387)); + memcpy(&c->trap_ctxt, + d->thread.traps, + sizeof(d->thread.traps)); +#ifdef ARCH_HAS_FAST_TRAP + if ( (d->thread.fast_trap_desc.a == 0) && + (d->thread.fast_trap_desc.b == 0) ) + c->fast_trap_idx = 0; + else + c->fast_trap_idx = + d->thread.fast_trap_idx; +#endif + c->ldt_base = d->mm.ldt_base; + c->ldt_ents = d->mm.ldt_ents; + c->gdt_ents = 0; + if ( GET_GDT_ADDRESS(d) == GDT_VIRT_START ) + { + for ( i = 0; i < 16; i++ ) + c->gdt_frames[i] = + l1_pgentry_to_pagenr(d->mm.perdomain_pt[i]); + c->gdt_ents = + (GET_GDT_ENTRIES(d) + 1) >> 3; + } + c->guestos_ss = d->thread.guestos_ss; + c->guestos_esp = d->thread.guestos_sp; + c->pt_base = + pagetable_val(d->mm.pagetable); + memcpy(c->debugreg, + d->thread.debugreg, + sizeof(d->thread.debugreg)); + c->event_callback_cs = + d->event_selector; + c->event_callback_eip = + d->event_address; + c->failsafe_callback_cs = + d->failsafe_selector; + c->failsafe_callback_eip = + d->failsafe_address; + + if ( d != current ) + domain_unpause(d); + + if ( copy_to_user(op->u.getdomaininfo.ctxt, c, sizeof(*c)) ) + ret = -EINVAL; + + if ( c != NULL ) + kfree(c); + } + + if ( copy_to_user(u_dom0_op, op, sizeof(*op)) ) + ret = -EINVAL; + + put_domain(d); + } + break; + + case DOM0_SHADOW_CONTROL: + { + struct domain *d; + ret = -ESRCH; + d = find_domain_by_id(op->u.shadow_control.domain); + if ( d != NULL ) + { + ret = shadow_mode_control(d, &op->u.shadow_control); + put_domain(d); + copy_to_user(u_dom0_op, op, sizeof(*op)); + } + } + break; + + default: + ret = -ENOSYS; + + } + + return ret; +} diff --git a/xen/common/debug.c b/xen/common/debug.c index fd2d7d28c3..1cf4c57d37 100644 --- a/xen/common/debug.c +++ b/xen/common/debug.c @@ -69,7 +69,7 @@ void pdb_do_debug (dom0_op_t *op) struct domain *d; d = find_domain_by_id(op->u.debug.domain); - if ( d->mm.shadow_mode ) + if ( shadow_mode(d) ) cr3 = pagetable_val(d->mm.shadow_table); else cr3 = pagetable_val(d->mm.pagetable); diff --git a/xen/common/dom0_ops.c b/xen/common/dom0_ops.c index 96d7197b3e..28b2671e5f 100644 --- a/xen/common/dom0_ops.c +++ b/xen/common/dom0_ops.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -25,23 +24,7 @@ #define TRC_DOM0OP_LEAVE_BASE 0x00030000 extern unsigned int alloc_new_dom_mem(struct domain *, unsigned int); - -static int msr_cpu_mask; -static unsigned long msr_addr; -static unsigned long msr_lo; -static unsigned long msr_hi; - -static void write_msr_for(void *unused) -{ - if (((1 << current->processor) & msr_cpu_mask)) - wrmsr(msr_addr, msr_lo, msr_hi); -} - -static void read_msr_for(void *unused) -{ - if (((1 << current->processor) & msr_cpu_mask)) - rdmsr(msr_addr, msr_lo, msr_hi); -} +extern long arch_do_dom0_op(dom0_op_t *op, dom0_op_t *u_dom0_op); long do_dom0_op(dom0_op_t *u_dom0_op) { @@ -271,127 +254,6 @@ long do_dom0_op(dom0_op_t *u_dom0_op) } break; - case DOM0_GETDOMAININFO: - { - full_execution_context_t *c; - struct domain *d; - unsigned long flags; - int i; - - read_lock_irqsave(&tasklist_lock, flags); - - for_each_domain ( d ) - { - if ( d->domain >= op->u.getdomaininfo.domain ) - break; - } - - if ( (d == NULL) || !get_domain(d) ) - { - read_unlock_irqrestore(&tasklist_lock, flags); - ret = -ESRCH; - break; - } - - read_unlock_irqrestore(&tasklist_lock, flags); - - op->u.getdomaininfo.domain = d->domain; - strcpy(op->u.getdomaininfo.name, d->name); - - op->u.getdomaininfo.flags = - (test_bit(DF_DYING, &d->flags) ? DOMFLAGS_DYING : 0) | - (test_bit(DF_CRASHED, &d->flags) ? DOMFLAGS_CRASHED : 0) | - (test_bit(DF_SHUTDOWN, &d->flags) ? DOMFLAGS_SHUTDOWN : 0) | - (test_bit(DF_CTRLPAUSE, &d->flags) ? DOMFLAGS_PAUSED : 0) | - (test_bit(DF_BLOCKED, &d->flags) ? DOMFLAGS_BLOCKED : 0) | - (test_bit(DF_RUNNING, &d->flags) ? DOMFLAGS_RUNNING : 0); - - op->u.getdomaininfo.flags |= d->processor << DOMFLAGS_CPUSHIFT; - op->u.getdomaininfo.flags |= - d->shutdown_code << DOMFLAGS_SHUTDOWNSHIFT; - - op->u.getdomaininfo.tot_pages = d->tot_pages; - op->u.getdomaininfo.max_pages = d->max_pages; - op->u.getdomaininfo.cpu_time = d->cpu_time; - op->u.getdomaininfo.shared_info_frame = - __pa(d->shared_info) >> PAGE_SHIFT; - - if ( op->u.getdomaininfo.ctxt != NULL ) - { - if ( (c = kmalloc(sizeof(*c))) == NULL ) - { - ret = -ENOMEM; - put_domain(d); - break; - } - - if ( d != current ) - domain_pause(d); - - c->flags = 0; - memcpy(&c->cpu_ctxt, - &d->shared_info->execution_context, - sizeof(d->shared_info->execution_context)); - if ( test_bit(DF_DONEFPUINIT, &d->flags) ) - c->flags |= ECF_I387_VALID; - memcpy(&c->fpu_ctxt, - &d->thread.i387, - sizeof(d->thread.i387)); - memcpy(&c->trap_ctxt, - d->thread.traps, - sizeof(d->thread.traps)); -#ifdef ARCH_HAS_FAST_TRAP - if ( (d->thread.fast_trap_desc.a == 0) && - (d->thread.fast_trap_desc.b == 0) ) - c->fast_trap_idx = 0; - else - c->fast_trap_idx = - d->thread.fast_trap_idx; -#endif - c->ldt_base = d->mm.ldt_base; - c->ldt_ents = d->mm.ldt_ents; - c->gdt_ents = 0; - if ( GET_GDT_ADDRESS(d) == GDT_VIRT_START ) - { - for ( i = 0; i < 16; i++ ) - c->gdt_frames[i] = - l1_pgentry_to_pagenr(d->mm.perdomain_pt[i]); - c->gdt_ents = - (GET_GDT_ENTRIES(d) + 1) >> 3; - } - c->guestos_ss = d->thread.guestos_ss; - c->guestos_esp = d->thread.guestos_sp; - c->pt_base = - pagetable_val(d->mm.pagetable); - memcpy(c->debugreg, - d->thread.debugreg, - sizeof(d->thread.debugreg)); - c->event_callback_cs = - d->event_selector; - c->event_callback_eip = - d->event_address; - c->failsafe_callback_cs = - d->failsafe_selector; - c->failsafe_callback_eip = - d->failsafe_address; - - if ( d != current ) - domain_unpause(d); - - if ( copy_to_user(op->u.getdomaininfo.ctxt, c, sizeof(*c)) ) - ret = -EINVAL; - - if ( c != NULL ) - kfree(c); - } - - if ( copy_to_user(u_dom0_op, op, sizeof(*op)) ) - ret = -EINVAL; - - put_domain(d); - } - break; - case DOM0_GETPAGEFRAMEINFO: { struct pfn_info *page; @@ -448,32 +310,6 @@ long do_dom0_op(dom0_op_t *u_dom0_op) } break; - case DOM0_MSR: - { - if ( op->u.msr.write ) - { - msr_cpu_mask = op->u.msr.cpu_mask; - msr_addr = op->u.msr.msr; - msr_lo = op->u.msr.in1; - msr_hi = op->u.msr.in2; - smp_call_function(write_msr_for, NULL, 1, 1); - write_msr_for(NULL); - } - else - { - msr_cpu_mask = op->u.msr.cpu_mask; - msr_addr = op->u.msr.msr; - smp_call_function(read_msr_for, NULL, 1, 1); - read_msr_for(NULL); - - op->u.msr.out1 = msr_lo; - op->u.msr.out2 = msr_hi; - copy_to_user(u_dom0_op, op, sizeof(*op)); - } - ret = 0; - } - break; - #ifdef XEN_DEBUGGER case DOM0_DEBUG: { @@ -543,20 +379,6 @@ long do_dom0_op(dom0_op_t *u_dom0_op) } break; - case DOM0_SHADOW_CONTROL: - { - struct domain *d; - ret = -ESRCH; - d = find_domain_by_id(op->u.shadow_control.domain); - if ( d != NULL ) - { - ret = shadow_mode_control(d, &op->u.shadow_control); - put_domain(d); - copy_to_user(u_dom0_op, op, sizeof(*op)); - } - } - break; - case DOM0_SCHED_ID: { op->u.sched_id.sched_id = sched_id(); @@ -696,7 +518,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op) break; default: - ret = -ENOSYS; + ret = arch_do_dom0_op(op,u_dom0_op); } diff --git a/xen/common/domain.c b/xen/common/domain.c index 5375a5de18..58ed42b25f 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include @@ -57,7 +56,7 @@ struct domain *do_createdomain(domid_t dom_id, unsigned int cpu) atomic_set(&d->refcnt, 1); atomic_set(&d->pausecnt, 0); - spin_lock_init(&d->mm.shadow_lock); + shadow_lock_init(d); d->domain = dom_id; d->processor = cpu; @@ -335,7 +334,7 @@ void domain_relinquish_memory(struct domain *d) write_ptbase(¤t->mm); /* Exit shadow mode before deconstructing final guest page table. */ - if ( d->mm.shadow_mode ) + if ( shadow_mode(d) ) shadow_mode_disable(d); /* Drop the in-use reference to the page-table base. */ diff --git a/xen/common/kernel.c b/xen/common/kernel.c index 92602e0bf5..23b0fb348d 100644 --- a/xen/common/kernel.c +++ b/xen/common/kernel.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include -- 2.30.2